package com.xinqi.modules.course.clazz.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.base.user.Account;
import com.xinqi.common.core.enums.ClassRoleEnum;
import com.xinqi.modules.course.clazz.domain.ClassStudentEntity;
import com.xinqi.modules.course.clazz.dto.ClassStudentAuditData;
import com.xinqi.modules.course.clazz.dto.req.*;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentMobileResultDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import com.xinqi.modules.user.user.dto.rsp.UserResultDTO;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 班级学生表服务层
 *
 * @author: system
 * @date: 2023/01/17
 */
public interface ClassStudentService {
    /**
     * 分页查询 班级学生表数据
     */
    PageInfo<ClassStudentResultDTO> page(Param pageable, ClassStudentQueryDTO query);

    /**
     * 查询 班级学生表数据
     */
    List<ClassStudentResultDTO> find(ClassStudentQueryDTO query);

    /**
     * 根据id查询 班级学生表数据
     */
    ClassStudentResultDTO findById(Long id);

    /**
     * 根据id查询，并对手机号脱敏
     *
     * @param id
     * @return
     */
    ClassStudentResultDTO findDetailByIdAndDesensitized(Long id);

    /**
     * 新增 班级学生表数据
     */
    Long insert(ClassStudentCreateDTO dto);

    /**
     * 根据id修改 班级学生表数据
     */
    Boolean updateById(ClassStudentUpdateDTO dto);

    /**
     * 根据id删除 班级学生表数据
     */
    Boolean deleteById(Long id);

    /**
     * 根据id删除 班级学生表数据
     */
    Boolean deleteById(ClassStudentDeleteDTO dto);


    Boolean teacherAddStudent(ClassStudentCreateDTO dto);

    /**
     * 只统计虚拟学生
     *
     * @param classId 班级id
     * @return 虚拟用户数量
     */
    int findAddedCountByClassId(Long classId);

    /**
     * 不包含老师
     *
     * @param classId
     * @param studentId
     * @return
     */
    ClassStudentEntity findByClassIdAndStudentId(Long classId, Long studentId, Integer isTeacher);

    /**
     * 包含老师
     *
     * @param classId
     * @param studentId
     * @return
     */
    ClassStudentResultDTO findAllRolesStudentByClassIdAndStudentId(Long classId, Long studentId);

    /**
     * 通过班级ID和学生ID查询班级成员（判断存在于班级中）
     *
     * @param classId
     * @param studentId
     * @return
     */
    ClassStudentEntity selectByClassIdAndStudentId(Long classId, Long studentId);

    ClassStudentResultDTO findByClassIdAndStudentId(Long classId, Long studentId);

    /**
     * 权限校验
     * <p>
     * 校验当前学生在班级中的角色，
     * 校验通过，返回学生实体，
     * 校验不通过，CommonErrors.BAD_REQUEST
     *
     * @param classId
     * @param studentId
     * @param classRoles
     * @return
     */
    ClassStudentResultDTO checkRole(Long classId, Long studentId, List<ClassRoleEnum> classRoles);

    /**
     * 校验是班级里的学生
     *
     * @param classId
     * @param userId
     * @return
     */
    Boolean checkIsStudent(Long classId, Long userId);

    Boolean insertTeacher(Long userId, Long courseId, Long classId);

    Boolean insertStudent(Long createBy, Long studentId, Long courseId, Long classId, Integer isRelationalStudent, Long patStuRefId, ClassAuditJsonParamDTO auditJsonParamDTO);

    PageInfo<ClassStudentResultDTO> pageList(Page<ClassStudentEntity> page, ClassStudentQueryDTO dto);

    /**
     * 可以根据多个角色查询
     *
     * @param page
     * @param dto
     * @return
     */
    PageInfo<ClassStudentResultDTO> pageListAndDesensitized(Page<ClassStudentEntity> page, ClassStudentAppQueryDTO dto);

    List<ClassStudentResultDTO> findByClassId(Long classId);

    Boolean teacherRemoveMasterBatch(Account user, Long classId, List<ClassStudentDeleteDTO> dtoList);

    List<ClassStudentResultDTO> findOutsideStudentList(ClassGroupStudentQueryDTO dto);

    List<ClassStudentResultDTO> findAllRolesStudentByCourseId(Long courseId);

    List<ClassStudentResultDTO> findByCourseIdAndStudentId(Long courseId, Long studentId);

    List<ClassStudentResultDTO> findByCourseIdAndStudentIdAndRoles(Long courseId, Long studentId, List<ClassRoleEnum> classRoles);

    List<ClassStudentResultDTO> findStudentExcludeTeacher(Long classId);

    List<ClassStudentResultDTO> findStudentExcludeTeacherByClassIdAndSearchKey(Long classId, String searchKey);

    List<ClassStudentResultDTO> findByClassIdAndRole(Long classId, ClassRoleEnum classRole);

    List<ClassStudentResultDTO> findByClassIdAndRoleAndIsRelationalStudent(Long classId, ClassRoleEnum classRole, Integer isRelationalStudent);

    List<ClassStudentEntity> findListByClassId(Long classId);

    List<ClassStudentEntity> findListByIds(List<Long> idList);

    Boolean saveBatch(List<ClassStudentEntity> studentEntityList);

    Boolean addBatch(List<ClassStudentEntity> studentEntityList);

    /**
     * 学生变更为课代表
     *
     * @param dto 学生实体
     * @return Boolean
     */
    Boolean masterStudentChangeRepresentative(ClassStudentUpdateDTO dto);

    Boolean relationalStudentChangeRepresentative(ClassStudentUpdateDTO dto);

    /**
     * 课代表变更为学生
     *
     * @param dto 学生实体
     * @return Boolean
     */
    Boolean masterRepresentativeChangeStudent(ClassStudentUpdateDTO dto);

    Boolean relationalRepresentativeChangeStudent(ClassStudentUpdateDTO dto);

    /**
     * 学生变更为助教
     *
     * @param dto 学生实体
     * @return Boolean
     */
    Boolean studentChangeAssistant(Account user, ClassStudentUpdateDTO dto);

    /**
     * 助教变更为学生
     *
     * @param dto 学生实体
     * @return Boolean
     */
    Boolean assistantChangeStudent(ClassStudentUpdateDTO dto);

    /**
     * 课代表变为助教
     *
     * @param dto 学生实体
     * @return Boolean
     */
    Boolean representativeChangeAssistant(Account user, ClassStudentUpdateDTO dto);

    /**
     * 助教变为课代表
     *
     * @param dto 学生实体
     * @return Boolean
     */
    Boolean assistantChangeRepresentative(ClassStudentUpdateDTO dto);

    /**
     * 查询并添加用户到班级
     *
     * @param searchKey 查询条件
     * @return Boolean
     */
    Boolean searchAndInsertStudent(Long id, String searchKey, ClassAuditJsonParamDTO auditContent);

    Integer deleteBatch(List<Long> ids);

    Boolean teacherBatchAddStudent(List<ClassStudentCreateDTO> dto);

    Boolean deleteByStudentId(Account user, Long studentId);

    List<ClassStudentEntity> findListContainsTeacherByClassId(Long classId);

    List<ClassStudentEntity> findByClassIdList(List<Long> classIdList);

    @Transactional(rollbackFor = Exception.class)
    void transferTeacherList(UserResultDTO receiver, List<ClassStudentEntity> classStudentList);

    List<ClassStudentEntity> findByClassIdListAndStudentId(List<Long> classIdList, Long studentId);

    List<ClassStudentResultDTO> findByClassIdListAndRoleList(List<Long> classIdList, List<ClassRoleEnum> roles);

    Integer findAddedClassCount();

    /**
     * 根据班级id查询班级总人数
     *
     * @param classId
     * @return
     */
    Long findClassStudentCountByClassId(Long classId);

    ClassStudentResultDTO findByStudentId(Long classId, Long studentId);

    List<ClassStudentResultDTO> findByClassRole(Long classId, String classRole);

    List<ClassStudentResultDTO> findStudentByStudentIdAndClassId(Long classId, List<Long> studentIds);

    ClassStudentEntity findTeacherByClass(Long classId);

    List<ClassStudentEntity> findTeacherListByClassIds(List<Long> classIdList);

    ClassStudentEntity getByStudentIdAndClassId(Long studentId, Long classId);

    List<ClassStudentEntity> findAllByClassId(Long classId);

    List<ClassStudentEntity> findTeacherAssistantByClass(Long classId);

    void checkStudentInClass(Long classId, Long studentId);

    void checkTeacherInClass(Long classId, Long studentId);

    /**
     * 获取班级学生列表不包括注销学生
     */
    List<ClassStudentResultDTO> studentListByClassId(Long classId);

    /**
     * 获取班级所有成员列表不包括注销用户
     */
    List<ClassStudentResultDTO> allUserListByClassId(Long classId);

    /**
     * 获取班级学生老师列表不包括注销用户
     */
    List<ClassStudentResultDTO> findContainsTeacherListByClassId(Long classId);

    /**
     * 批量添加学生信息
     */
    void saveAllStudent(List<ClassStudentEntity> list);

    /**
     * 根据班级id和手机号查询学生
     *
     * @param classId 班级id
     * @param mobile  手机号
     * @return ClassStudentResultDTO
     */
    ClassStudentResultDTO findByClassIdAndMobile(Long classId, String mobile);

    /**
     * 添加助教
     *
     * @param classId 班级id
     * @param userId  助教的用户id
     */
    Boolean addAssistant(Long classId, Long userId);

    /**
     * 根据用户id（一般为登录用户id，也可以自己指定用户id）查询虚拟学生
     *
     * @param classId 班级id
     * @param userId  用户id
     * @return ClassStudentResultDTO
     */
    ClassStudentResultDTO findVirtualClassStudentByClassIdAndUserId(Long classId, Long userId);

    /**
     * 根据主用户id 查询关系用户集合
     *
     * @param classId 班级id
     * @param userIds 用户id集合
     * @return ClassStudentResultDTO
     */
    List<ClassStudentResultDTO> findRelationshipStudentByClassIdAndUserIds(Long classId, List<Long> userIds);

    /**
     * 根据班级id和模拟学生id查询关系学生列表
     *
     * @param classId   班级id
     * @param studentId 模拟学生的学生id
     * @return List<ClassStudentResultDTO>
     */
    List<ClassStudentResultDTO> findRelationStudentByClassIdAndImitateStudentId(Long classId, Long studentId);

    Boolean teacherRemoveRelationalStudentBatch(Long classId, List<ClassStudentDeleteDTO> dtoList);

    List<ClassStudentResultDTO> findClassMasterStudentByClassId(Long classId);

    List<ClassStudentEntity> findStudentByClassIdAndIsRelationshipAndIds(Long classId, Integer isRelationStudent, List<Long> ids);

    List<ClassStudentResultDTO> findClassRelationStudentByClassId(Long classId);

    List<ClassStudentResultDTO> findClassMasterStudentByClassIdList(List<Long> classIdList);

    List<ClassStudentEntity> findRelationStudentListByClassIdAndMasterIdList(Long classId, List<Long> masterStudentIdList);

    Boolean updateMasterStudent(MasterClassStudentUpdateDTO dto);

    Long findAllCountByClassId(Long classId);

    /**
     * 根据班级id和学生id查询班级下的主学生、虚拟学生列表
     *
     * @param classId   班级id
     * @param studentId 学生id
     * @return List<ClassStudentEntity>
     */
    List<ClassStudentEntity> findMasterAndRelationStudentByClassIdAndImitateStudentId(Long classId, Long studentId);

    List<ClassStudentEntity> findMasterAndRelationStudentByClassIdAndRelationStudentId(Long classId, Long relationId);

    List<ClassStudentMobileResultDTO> findImitateStudentMobileList(ClassImitateStudentQueryDTO dto);

    void repairAuditContent(Long classId, ClassStudentAuditData dto);

    /**
     * 根据班级id和用户id查询班级下的学生、可以查老师
     *
     * @param classId 班级id
     * @param userId  学生id
     */
    ClassStudentResultDTO findClassStudentContainTeacherByClassIdAndUserId(Long classId, Long userId);

    Boolean teacherRemoveAssistant(Account xqLoginUser, Long classId, Long assistantId);

    ClassStudentResultDTO findByClassAndClassStudentIdAndClasRole(Long classId, Long id, ClassRoleEnum classRole);

    ClassStudentResultDTO findByClassIdAndStudentName(Long classId, String studentName);
}
